<?php
require_once 'Zend/Sql/Parser.php';

class Zend_Sql_Adapter_MySql_Statement_Select
	extends Zend_Sql_Adapter_Standard_Statement_Select
{
	// {{{ parseSelect()
	/**
	 * @access  public
	 * @return mixed array parsed select on success, otherwise Error
	 */
	public function parseSelect($subSelect = false)
	{
		$tree = array('command' => 'select');
		$this->getTok();
		if ($this->token == 'distinct' || $this->token == 'all') {
			$tree['set_quantifier'] = $this->token;
			$this->getTok();
		}

		while (1) {
			$tree['select_expressions'][] = $this->parseCondition();
			if ($this->token != ',') {
				break;
			}
			$this->getTok();
		}

		// FROM
		if ($this->token != 'from') {
			return $tree;
		}

		$this->getTok();
		$tree['from'] = $this->parseFrom();

		// WHERE

		// GROUP BY

		// HAVING

		// ORDER BY

		// LIMIT

		// UNION
		while ($this->token != ';' && ! is_null($this->token) && (!$subSelect || $this->token != ')')
		&& $this->token != ')') {
			switch ($this->token) {
				case 'where':
					$this->getTok();
					$clause = $this->parseCondition();
					if (false === $clause) {
						return $clause;
					}
					$tree['where_clause'] = $clause;
					break;
				case 'order':
					$this->getTok();
					if ($this->token != 'by') {
						$this->raiseError('Expected "by"');
					}
					$this->getTok();
					while ($this->token == 'ident') {
						$arg = $this->lexer->tokText;
						$this->getTok();
						if ($this->token == '.') {
							$this->getTok();
							if ($this->token == 'ident') {
								$arg .= '.'.$this->lexer->tokText;
							} else {
								$this->raiseError('Expected a column name');
							}
						} else {
							$this->lexer->pushBack();
						}
						$col = $arg;
						//$col = $this->lexer->tokText;
						$this->getTok();
						if (isset($this->synonyms[$this->token])) {
							$order = $this->synonyms[$this->token];
							if (($order != 'asc') && ($order != 'desc')) {
								$this->raiseError('Unexpected token');
							}
							$this->getTok();
						} else {
							$order = 'asc';
						}
						if ($this->token == ',') {
							$this->getTok();
						}
						$tree['sort_order'][$col] = $order;
					}
					break;
				case 'limit':
					$this->getTok();
					if ($this->token != 'int_val') {
						$this->raiseError('Expected an integer value');
					}
					$length = $this->lexer->tokText;
					$start = 0;
					$this->getTok();
					if ($this->token == ',') {
						$this->getTok();
						if ($this->token != 'int_val') {
							$this->raiseError('Expected an integer value');
						}
						$start  = $length;
						$length = $this->lexer->tokText;
						$this->getTok();
					}
					$tree['limit_clause'] = array('start'=>$start,
                    'length'=>$length);
					break;
				case 'group':
					$this->getTok();
					if ($this->token != 'by') {
						$this->raiseError('Expected "by"');
					}
					$this->getTok();
					while ($this->token == 'ident') {
						$arg = $this->lexer->tokText;
						$this->getTok();
						if ($this->token == '.') {
							$this->getTok();
							if ($this->token == 'ident') {
								$arg .= '.'.$this->lexer->tokText;
							} else {
								$this->raiseError('Expected a column name');
							}
						} else {
							$this->lexer->pushBack();
						}
						$col = $arg;
						//$col = $this->lexer->tokText;
						$this->getTok();
						if ($this->token == ',') {
							$this->getTok();
						}
						$tree['group_by'][] = $col;
					}
					break;
				default:
					$this->raiseError('Unexpected clause');
			}
		}
		return $tree;
	}
	// }}}

}
